#include <iostream>
#include <pthread.h>
#include <unistd.h>

using namespace std;

// 锁
pthread_mutex_t g_mutex;

void printer(const char * str)
{
    // 加锁
    pthread_mutex_lock(&g_mutex);
    while (*str)
    {
        putchar(*str);
        fflush(stdout);
        str++;

        sleep(1);
    }

    // 解锁
    pthread_mutex_unlock(&g_mutex);
}

// 线程 1
void *thread_func1(void *arg)
{
    // 线程 tid1 获取锁，输出 "hello" 的五个字符，每输出一个字符休眠 1 秒，总共 5 秒后释放锁。
    const char *str = "hello";
    printer(str);

    // 线程退出
    pthread_exit(NULL);
}

// 线程 2
void *thread_func2(void *arg)
{
    // 线程 tid2 获取锁，开始输出 "world" 的五个字符，同样每输出一个字符休眠 1 秒，总共 5 秒后释放锁。
    const char *str = "world";
    printer(str);

    // 线程 tid2 在循环中打印 "I am thread_func2"
    // 因为这部分没有加锁，所以可能与主线程的输出同时进行。
    int count = 10000;
    while (count--)
    {
        cout << "I am thread_func2" << endl;
        sleep(1);
    }

    // 线程退出
    pthread_exit(NULL);
}

int main()
{
    // 初始化锁
    pthread_mutex_init(&g_mutex, NULL);

    pthread_t tid1;
    pthread_create(&tid1, NULL, thread_func1, NULL); 

    pthread_t tid2;
    pthread_create(&tid2, NULL, thread_func2, NULL); 

    // 主线程完成 60 秒倒计时后，直接结束程序
    // 即使线程 2 的循环还没结束，也会被强制终止，因为进程结束时所有关联的线程都会被终止
    // 如果希望主线程在倒计时结束后等待子线程的完成，需要使用 pthread_join 函数
    // 它可以阻塞主线程，直到指定的子线程执行完毕为止。
    int cnt = 60;
    while (cnt--)
    {
        sleep(1);
    }

    // 释放锁
    pthread_mutex_destroy(&g_mutex);

    return 0;
}